import G6, {G6GraphEvent, Graph, ModelConfig} from '@antv/g6';
import {G6Event} from '@antv/g6-core/lib/types';
import React from 'react';
import NodeType from '../consts/node-type';
import GraphKeyName from '../consts/graph-key-name';

/**
 * 显示拖动时的阴影
 */
export default function () {
    G6.registerBehavior('custom:ghost-node:display', {
        getDefaultCfg() {
            return {

            };
        },
        getEvents() {
            return {
                'custom:ghost-node:display': 'handleGhostDisplay',
                'custom:ghost-nodes:display': 'handleGhostsDisplay',
            } as {
                [key in G6Event]?: string;
            };
        },
        handleGhostsDisplay(event: React.DragEvent | G6GraphEvent) {
            const graph = this.graph as Graph;
            const dragNodeIds = graph.get(GraphKeyName.DRAG_NODE_IDS);
            if (!dragNodeIds) {
                return ;
            }

            const { x, y } = graph.get(GraphKeyName.DRAG_NODE_START_POINT);

            dragNodeIds.forEach((dragNodeId: string) => {
                let nodeType = NodeType.USER_TASK;
                if (dragNodeId) {
                    const originNode = graph.findById(dragNodeId);
                    nodeType = originNode.getModel().type as string;

                    const zoom = graph.getZoom();
                    const { clientX, clientY } = event;
                    const offsetX = (clientX - x) / zoom;
                    const offsetY = (clientY - y) / zoom;

                    const ghostX = originNode.getModel().x as number + offsetX;
                    const ghostY = originNode.getModel().y as number + offsetY;

                    // const {x, y} = graph.getPointByClient(event.clientX, event.clientY);
                    const targetX = Math.round(ghostX / 10) * 10;
                    const targetY = Math.round(ghostY / 10) * 10;

                    const ghostId = `ghost-${dragNodeId}`;
                    const currentGhost = graph.findById(ghostId);
                    if (!currentGhost || currentGhost.getModel().x !== targetX || currentGhost.getModel().y !== targetY) {
                        const model = {
                            clazz: nodeType,
                            x: targetX,
                            y: targetY,
                            id: ghostId,
                            type: nodeType,
                        } as ModelConfig;
                        graph.removeItem(ghostId, false);
                        graph.addItem('node', model, false);
                    }
                }
            });
        },
        handleGhostDisplay(event: React.DragEvent | G6GraphEvent) {
            // console.log('handleGhostDisplay');
            const graph = this.graph as Graph;
            const dragNodeIds = graph.get(GraphKeyName.DRAG_NODE_IDS);

            let nodeType = NodeType.USER_TASK;
            if (!(event instanceof G6GraphEvent)) {
                nodeType = ((event as React.DragEvent).target as HTMLElement).getAttribute('node-type') as string;
            } else {
                nodeType = (event as G6GraphEvent).item.getModel().type as string;
            }

            if (!nodeType && !dragNodeIds) {
                return ;
            }

            if (dragNodeIds) {
                const targetNode = graph.findById(dragNodeIds);
                nodeType = targetNode.getModel().type as string;
            }

            const {x, y} = graph.getPointByClient(event.clientX, event.clientY);
            const targetX = Math.round(x / 10) * 10;
            const targetY = Math.round(y / 10) * 10;

            const currentGhost = graph.findById('ghost');
            if (!currentGhost || currentGhost.getModel().x !== targetX || currentGhost.getModel().y !== targetY) {

                const model = {
                    clazz: nodeType,
                    x: targetX,
                    y: targetY,
                    id: 'ghost',
                    type: nodeType,
                } as ModelConfig;
                graph.removeItem('ghost', false);
                graph.addItem('node', model);
            }
        }
    });
}
